const PADDING = 'padding'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class MyPromise {
  #status = PADDING
  #result
  #cb = {}
  #isCanRun = false
  constructor (cb) {
    const resolve = (data) => {
      this.updateStatus(FULFILLED, data)
    }
    const reject = (err) => {
      this.updateStatus(REJECTED, err)
    }
    cb(resolve, reject)
  }

  updateStatus (status, data) {
    // 状态一旦发生变更 再也不会修改
    if (this.#status !== PADDING) return
    this.#status = status
    this.#result = data
    this.run()
  }

  run () {
    if (!this.#isCanRun) return
    switch (this.#status) {
      case FULFILLED:
        this.#cb.success(this.#result)
        break
      case REJECTED:
        this.#cb.error(this.#result)
        break
    }
    return new MyPromise((resolve, reject) => {
      switch (this.#status) {
        case FULFILLED:
          resolve(this.#result)
          break
        case REJECTED:
          reject(this.#result)
          break
      }
    })
  }

  then (success, error) {
    this.#isCanRun = true
    this.#cb.success = success
    this.#cb.error = error
    return this.run()
  }

  catch (error) {
    this.#isCanRun = true
    if (!this.#cb.error) {
      this.#cb.error = error
    }
    return this.run()
  }
}

const myPromise = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    reject(1)
  }, 1000)
}).then((res) => {
  console.log('成功', res)
}, (err) => {
  console.log('失败', err)
}).catch(err => {
  console.log('失败catch', err)
})
